package com.smzd.ccms.actions;

import java.util.Date;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.smzd.ccms.business.ArticleService;
import com.smzd.ccms.core.CompletPluginManager;
import com.smzd.ccms.domain.Article;
import com.smzd.ccms.domain.Channel;
import com.smzd.ccms.domain.ChannelConfig;
import com.smzd.ccms.domain.Site;
import com.smzd.framework.annotation.Access;
import com.smzd.framework.core.actions.AbstractScopedController;
import com.smzd.framework.core.business.IFGService;
import com.smzd.framework.utils.MeetingSessionHolder;
import com.smzd.framework.utils.db.SRPage;
import com.smzd.utils.SessionHolder;

@Controller
@RequestMapping("/a/{site}/articles/{channel}")
@Access("TAG_ROLE_CCMS")
public class ArticleController extends AbstractScopedController<Article, Channel> {
    @Autowired
    private ArticleService service;

    @Override
    protected IFGService<Article> getService() {
        return service;
    }

    @Override
    protected Channel getScope(int scopeId) {
        return SessionHolder.getObject(Channel.SESSION_KEY_CURRENT_CHANNEL);
    }

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public String toAddPage(Map<String, Object> model, @PathVariable("site") String siteStr,
            @PathVariable("channel") String channelStr, Article elem, BindingResult result) throws Exception {
        Channel channel = initAndCheckScope(model, siteStr, channelStr);
        String defaultView = super.toAddPage(model, channel.getId(), elem, result);
        if (channel.getType() >= Channel.TYPE_ISOMER_NORMAL) {// 应该不会发生，因为异构类型的文章增加会有自己的后台列表和新增/编辑页面
            return defaultView;
        }
        ChannelConfig ccfg = channel.getChannelConfig(4);
        return retrieveBackgroundView(defaultView, ccfg);
    }

    private String retrieveBackgroundView(String defaultView, ChannelConfig ccfg) {
        return ccfg == null ? defaultView : "ccms/templates/" + ccfg.getTemplate().getPath();
    }

    /**
     * 确认给出的栏目参数和站点参数是匹配的。然后返回栏目的对象。
     * 
     * @param model
     * @param siteStr
     * @param channelStr
     * @return
     * @throws Exception
     */
    private Channel initAndCheckScope(Map<String, Object> model, String siteStr, String channelStr) throws Exception {
        Site site = CompletPluginManager.getSite(siteStr);
        if (site == null) {
            throw new Exception("站点不存在！");
        }
        SessionHolder.setObject(Site.SESSION_KEY_CURRENT_SITE, site);// XXX
                                                                     // 这是干嘛用的？这个很复杂，应该想个办法消除掉通过session传值。
        model.put("_site_", siteStr);
        model.put("_site", site);
        Channel channel = site.getChannel(channelStr);
        if (channel == null) {
            throw new Exception("栏目不存在！");
        }
        SessionHolder.setObject(Channel.SESSION_KEY_CURRENT_CHANNEL, channel);// XXX
                                                                              // 这个是准备给getScope用的，不应该这样用。最多用threadlocal。
        model.put("_channel_", channelStr);
        model.put("_channel", channel);
        return channel;
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ResponseBody
    public String postAddData(Map<String, Object> model, @PathVariable("site") String siteStr,
            @PathVariable("channel") String channelStr, Article elem, BindingResult result) throws Exception {
    	Channel channel = initAndCheckScope(model, siteStr, channelStr);
        Date date = new Date();
        elem.setPosttime(date);
        elem.setLastmodified(date);
        elem.setSticky(0);
        elem.setStatus(0);
        elem.setUser(MeetingSessionHolder.getLoginUser());
        return super.postAddData(model, channel.getId(), elem, result);
    }

    /**
     * 后台文章列表展示页面。没有添加配置。如果添加了，需要影响到后面的返回视图。
     * 
     * @param model
     * @param siteStr
     * @param channelStr
     * @param elem
     * @param result
     * @return
     * @throws Exception
     */
    @RequestMapping(value = { "", "/index.html" }, method = RequestMethod.GET)
    public String toListPage(Map<String, Object> model, @PathVariable("site") String siteStr,
            @PathVariable("channel") String channelStr, Article elem, BindingResult result) throws Exception {
        Channel channel = initAndCheckScope(model, siteStr, channelStr);
        String defaultView = super.toListPage(model, channel.getId(), elem, result);
        if (channel.getType() >= Channel.TYPE_ISOMER_NORMAL) {// 这时其实不会调用这个方法，因为会单独配置后台列表页面
            return defaultView;
        }
        ChannelConfig ccfg = channel.getChannelConfig(3);
        return retrieveBackgroundView(defaultView, ccfg);
    }

    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @ResponseBody
    public String getListData(Map<String, Object> model, @PathVariable("site") String siteStr,
            @PathVariable("channel") String channelStr, SRPage<Channel, Article> page, BindingResult result)
            throws Exception {
        Channel channel = initAndCheckScope(model, siteStr, channelStr);
        return super.getListData(model, channel.getId(), page, result);
    }

    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String toEditPage(Map<String, Object> model, @PathVariable("site") String siteStr,
            @PathVariable("channel") String channelStr, Article elem, BindingResult result) throws Exception {
        Channel channel = initAndCheckScope(model, siteStr, channelStr);
        elem = service.getItemById(elem.getId());
        String defaultView = super.toEditPage(model, channel.getId(), elem, result);
        if (channel.getType() >= Channel.TYPE_ISOMER_NORMAL) { // 异构类型的编辑应该是有自己的页面，不会调到这里的
            return defaultView;
        }
        ChannelConfig ccfg = channel.getChannelConfig(3);
        return retrieveBackgroundView(defaultView, ccfg);
    }

    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    @ResponseBody
    public String postEditData(Map<String, Object> model, @PathVariable("site") String siteStr,
            @PathVariable("channel") String channelStr, Article elem, BindingResult result) throws Exception {
        Channel channel = initAndCheckScope(model, siteStr, channelStr);
        Date date = new Date();
        elem.setLastmodified(date);
//        elem.setStatus(0);
        return super.postEditData(model, channel.getId(), elem, result);
    }

    @RequestMapping(value = "/remove", method = RequestMethod.POST)
    @ResponseBody
    public String postRemoveData(Map<String, Object> model, @PathVariable("site") String siteStr,
            @PathVariable("channel") String channelStr, Article elem, BindingResult result) throws Exception {
        Channel channel = initAndCheckScope(model, siteStr, channelStr);
        return super.postRemoveData(model, channel.getId(), elem, result);
    }

}